﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using O2DESNet;
using ShkSimulation.core.dao.statistic;
using ShkSimulation.core.template.customer;
using ShkSimulation.core.template.model;
using ShkSimulation.core.util;
using ShkSimulation.carsharing.impl.model;
using ShkSimulation.carsharing.impl.util;

namespace ShkSimulation.carsharing.impl.elements {
	
	public partial class Station {
		
		public Station(BaseAgencyParams baseAgencyParams, List<Vehicle> vehicle) : base(baseAgencyParams) {
			this.Vehicles = new PriorityQueue<Vehicle>(vehicle, VehicleBatteryComparator.Instance);
			QueuingVehicleCounter = AddHourCounter();
			ServingVehicleCounter = AddHourCounter(); 
			FreeStationVehicleCounter = AddHourCounter();
			StationVehicleCounter = AddHourCounter();
			ServedCustomerCounter = AddHourCounter();
			ServiceTimeCounter = AddHourCounter();
			ServiceIntervalCounter = AddHourCounter();
			VirtualSpaceCounter = AddHourCounter();
			VirtualSpaceVehicle = new PriorityQueue<Vehicle>(VehicleBatteryComparator.Instance);
			DownStreamRoad = new List<Road>();
			//TODO
			StationVehicleCounter.ObserveCount(vehicle.Count, ClockTime);
			FreeStationVehicleCounter.ObserveCount(vehicle.Count, ClockTime);
			
			reportRelatedProperty["车辆数"] = StationVehicleCounter.AsReadOnly();
			//reportRelatedProperty["虚拟空间车辆数"] = VirtualSpaceCounter.AsReadOnly();
			//reportRelatedProperty["可用车辆数"] = FreeStationVehicleCounter.AsReadOnly();
			reportRelatedProperty["服务完的顾客数"] = ServedCustomerCounter.AsReadOnly();
			//reportRelatedProperty["排队长度"] = QueuingVehicleCounter.AsReadOnly();
			//reportRelatedProperty["服务时间"] = ServiceTimeCounter.AsReadOnly();
			//reportRelatedProperty["服务间隔"] = ServiceIntervalCounter.AsReadOnly();
			ServiceRateHelper = new StationServiceRateHelper(this);
		}

		public double ServiceRateLower = 1;
		public double ServiceRateUpper = 20;
		HourCounter VirtualSpaceCounter { get; set; }
		HourCounter QueuingVehicleCounter { get; set; }
		HourCounter ServingVehicleCounter { get; set; }
		HourCounter FreeStationVehicleCounter { get; set; }
		HourCounter StationVehicleCounter { get; set; }
		HourCounter ServiceTimeCounter { get; set; }
		HourCounter ServiceIntervalCounter { get; set; }
		HourCounter ServedCustomerCounter { get; set; }
		
		public double Income { get; private set; }
		public double TotalCost { get; private set; }

		public int AllVehicleCount {
			get { return (int)StationVehicleCounter.LastCount; }
		}
		
		public int FreeVehicleCount {
			get { return (int)FreeStationVehicleCounter.LastCount; }
		}

		public double Capacity { get; set; }
		public double Longitude { get; set; }
		public double Latitude { get; set; }
		public TimeSpan ServiceMinutes { get; set; }


		public int TravelerArriveCount { get; private set; }
		public int TravelerServeCount { get; private set; }
		public int TravelerRejectByNoVehicle { get; private set; }
		public int TravelerRejectByVehicleNoBattery { get; private set; }

		public int DispatcherArriveCount { get; private set; }
		public int DispatcherServeCount { get; private set; }
		public int DispatcherRejectByNoVehicle { get; private set; }
		public int DispatcherRejectByVehicleNoBattery { get; private set; }
		
		private Dictionary<string, ReadOnlyHourCounter> reportRelatedProperty =
			new Dictionary<string, ReadOnlyHourCounter>();		
		private Dictionary<string, double> reportRelatedDoubleData =
			new Dictionary<string, double>();

		/**
        * @description: DataReport
        */
		public override DataReportInfo GetReportInfo() {
			reportRelatedDoubleData["到达顾客数"] = TravelerArriveCount;
			reportRelatedDoubleData["服务顾客数"] = TravelerServeCount;
			reportRelatedDoubleData["总收入"] = Income;
			reportRelatedDoubleData["总成本"] = TotalCost;
			reportRelatedDoubleData["净利润"] = Income - TotalCost;
			//reportRelatedDoubleData["顾客接受率"] = TravelerReceiveRate;
			//reportRelatedDoubleData["调度员到达数"] = DispatcherArriveCount;
			//reportRelatedDoubleData["调度员服务数"] = DispatcherServeCount;
			//reportRelatedDoubleData["调度成功率"] = DispatcherReceiveRate;
			return DataReportInfo.Create(Uniquekey, ClockTime, reportRelatedProperty, reportRelatedDoubleData).Merge(InternalAgencyChain.GetReportInfo());
		}

		public double TravelerReceiveRate {
			get { return TravelerServeCount * 1.0 / TravelerArriveCount; }
		}

		public double DispatcherReceiveRate {
			get { return DispatcherServeCount * 1.0 / DispatcherArriveCount; }
		}
		
		public override ServiceRateHelper ServiceRateHelper { get; set; }

		public List<Road> DownStreamRoad { get; set; }

		private void CountArrive(CarsharingTraveler traveler) {
			if (!traveler.IsDispatcher) {
				this.TravelerArriveCount++;
			} else {
				this.DispatcherArriveCount++;
			}
		}

		private void CountServe(CarsharingTraveler traveler) {
			if (!traveler.IsDispatcher) {
				this.TravelerServeCount++;
			} else {
				this.DispatcherServeCount++;
			}
		}
		
		private bool VehicleAvailable(AbstractTraveler traveler) {
			Vehicle curVehicle = PeekFreeVehicle();
			Debug.Assert(FreeVehicleCount == (Vehicles.Count + VirtualSpaceVehicle.Count));
			Road road = (Road)traveler.GetAgencies()[1];
			if (curVehicle == null) {
				TravelerRejectByNoVehicle++;
				return false;
			}/*else if (!curVehicle.BatteryEnough(ClockTime, road.RoadLength)) {
				TravelerRejectByVehicleNoBattery++;
				return false;
			}*/
			return true;
		}

		public override string ToString() {
			return $"{"唯一Key"}: {UniqueId}\n" +
			       $"{"车辆数"}: {AllVehicleCount}\n" +
			       $"{"等待服务顾客数"}: {WaitServeList.Count}\n" +
			       $"{"全部到达顾客数"}: {TravelerArriveCount}\n" +
			       $"{"服务完的顾客数"}: {ServedCustomerCounter.LastCount}\n" +
			       $"{"调度员数量"}: {Dispatchers.Count}\n" +
			       $"{"总收入"}: {Income}\n" + 
			       $"{"总成本"}: {TotalCost}\n" + 
			       $"{"净利润"}: {Income - TotalCost}\n" + 
			       $"{"平均服务时间"}: {TimeSpan.FromHours(ServiceTimeCounter.AverageCount)}\n" +
			       $"{"车站容量"}: {Capacity}\n" +
			       $"{"经度"}: {Longitude}\n" +
			       $"{"纬度"}: {Latitude}\n" +
			       $"{"服务时长"}: {ServiceMinutes}";
		}
		
	}
}